<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>噪声生成复杂的纹理-simplex noise</title>
    <style>
        canvas{
            border:1px solid #ccc;
        }
    </style>
</head>
<body>
    <canvas width="554" height="554"></canvas>

    <script src="/common/lib/gl-renderer.js"></script>

    <script type="module">
        import { grayMatrix } from "/review/common/lib/utils.js"

        /**
         * 1.创建renderer对象
         * 2.创建webgl程序
         * 3.创建uniform变量
         * 4.将数据存入缓冲区
         * 5.渲染
         * */ 

        //  1.
        const canvas = document.querySelector("canvas");
        const renderer = new GlRenderer(canvas);

        (async function(){
            // 2.
            const vertex = `
                attribute vec2 a_vertexPosition;
                attribute vec2 uv;
                varying vec2 vUv;

                void main(){
                    vUv = uv;
                    gl_Position = vec4(a_vertexPosition, 1.0, 1.0);
                }
            `;
            const fragment = `
                #ifdef GL_ES
                    precision mediump float;
                #endif

                uniform float uTime;
                varying vec2 vUv;

                vec3 mod289(vec3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }
                vec2 mod289(vec2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }
                vec3 permute(vec3 x) { return mod289(((x*34.0)+1.0)*x); }
                //
                // Description : GLSL 2D simplex noise function
                //      Author : Ian McEwan, Ashima Arts
                //  Maintainer : ijm
                //     Lastmod : 20110822 (ijm)
                //     License :
                //  Copyright (C) 2011 Ashima Arts. All rights reserved.
                //  Distributed under the MIT License. See LICENSE file.
                //  https://github.com/ashima/webgl-noise
                //
                float noise(vec2 v) {
                    // Precompute values for skewed triangular grid
                    const vec4 C = vec4(0.211324865405187,
                                        // (3.0-sqrt(3.0))/6.0
                                        0.366025403784439,
                                        // 0.5*(sqrt(3.0)-1.0)
                                        -0.577350269189626,
                                        // -1.0 + 2.0 * C.x
                                        0.024390243902439);
                                        // 1.0 / 41.0

                    // First corner (x0)
                    vec2 i  = floor(v + dot(v, C.yy));
                    vec2 x0 = v - i + dot(i, C.xx);

                    // Other two corners (x1, x2)
                    vec2 i1 = vec2(0.0);
                    i1 = (x0.x > x0.y)? vec2(1.0, 0.0):vec2(0.0, 1.0);
                    vec2 x1 = x0.xy + C.xx - i1;
                    vec2 x2 = x0.xy + C.zz;

                    // Do some permutations to avoid
                    // truncation effects in permutation
                    i = mod289(i);
                    vec3 p = permute(
                            permute( i.y + vec3(0.0, i1.y, 1.0))
                                + i.x + vec3(0.0, i1.x, 1.0 ));

                    vec3 m = max(0.5 - vec3(
                                        dot(x0,x0),
                                        dot(x1,x1),
                                        dot(x2,x2)
                                        ), 0.0);

                    m = m*m ;
                    m = m*m ;

                    // Gradients:
                    //  41 pts uniformly over a line, mapped onto a diamond
                    //  The ring size 17*17 = 289 is close to a multiple
                    //      of 41 (41*7 = 287)
                    vec3 x = 2.0 * fract(p * C.www) - 1.0;
                    vec3 h = abs(x) - 0.5;
                    vec3 ox = floor(x + 0.5);
                    vec3 a0 = x - ox;

                    // Normalise gradients implicitly by scaling m
                    // Approximation of: m *= inversesqrt(a0*a0 + h*h);
                    m *= 1.79284291400159 - 0.85373472095314 * (a0*a0+h*h);

                    // Compute final noise value at P
                    vec3 g = vec3(0.0);
                    g.x  = a0.x  * x0.x  + h.x  * x0.y;
                    g.yz = a0.yz * vec2(x1.x,x2.x) + h.yz * vec2(x1.y,x2.y);
                    return 130.0 * dot(m, g);
                }
                void main() {
                    vec2 st = vUv * 20.0;
                    gl_FragColor.rgb = vec3(0.5 * noise(st) + 0.5);
                    gl_FragColor.a = 1.0;
                }
            `;

            const program = renderer.compileSync(fragment,vertex);
            renderer.useProgram(program);

            // 3.
            renderer.uniforms.uTime = 0.0;
            // 4.
            renderer.setMeshData([{
                positions:[
                    [-1, -1],
                    [-1, 1],
                    [1, 1],
                    [1, -1],
                ],
                attributes:{
                    uv:[
                        [0, 0],
                        [0, 1],
                        [1, 1],
                        [1, 0],
                    ]
                },
                cells: [[0, 1, 2], [2, 0, 3]],
            }]);

            // 5.
            renderer.render();

        })();
        
    </script>
</body>
</html>